package com.rbac.common.config;

import com.rbac.modules.system.entity.SysPermission;
import com.rbac.modules.system.entity.SysRole;
import com.rbac.modules.system.entity.SysUser;
import com.rbac.modules.system.entity.SysUserRole;
import com.rbac.modules.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Component
public class PermissionInitConfig implements CommandLineRunner {

    @Autowired
    private ApplicationContext applicationContext;

    private SysPermissionService permissionService;
    private SysRolePermissionService rolePermissionService;
    private SysRoleService roleService;
    private SysUserService userService;
    private SysUserRoleService userRoleService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void run(String... args) {
        // 延迟初始化Service
        initServices();

        // 检查是否已有用户数据
        if (userService.count() > 0) {
            log.info("系统数据已存在，跳过初始化");
            return;
        }

        log.info("开始初始化系统数据...");

        // 1. 初始化角色
        List<SysRole> roles = initRoles();

        // 2. 初始化权限
        List<SysPermission> permissions = initPermissions();

        // 3. 初始化用户
        List<SysUser> users = initUsers();

        // 4. 初始化角色权限关联
        initRolePermissions(roles, permissions);

        // 5. 初始化用户角色关联
        initUserRoles(users, roles);

        log.info("系统数据初始化完成");
    }

    /**
     * 延迟初始化Service
     */
    private void initServices() {
        permissionService = applicationContext.getBean(SysPermissionService.class);
        rolePermissionService = applicationContext.getBean(SysRolePermissionService.class);
        roleService = applicationContext.getBean(SysRoleService.class);
        userService = applicationContext.getBean(SysUserService.class);
        userRoleService = applicationContext.getBean(SysUserRoleService.class);
    }

    private List<SysRole> initRoles() {
        List<SysRole> roles = new ArrayList<>();

        // 超级管理员角色
        SysRole adminRole = new SysRole();
        adminRole.setRoleName("超级管理员");
        adminRole.setRoleCode("ROLE_ADMIN");
        adminRole.setDescription("系统超级管理员");
        adminRole.setStatus(1);
        roles.add(adminRole);

        // 普通用户角色
        SysRole userRole = new SysRole();
        userRole.setRoleName("普通用户");
        userRole.setRoleCode("ROLE_USER");
        userRole.setDescription("系统普通用户");
        userRole.setStatus(1);
        roles.add(userRole);

        // 批量保存角色
        roleService.saveBatch(roles);
        return roles;
    }

    private List<SysPermission> initPermissions() {
        List<SysPermission> permissions = new ArrayList<>();

        // 系统管理菜单
        SysPermission systemMenu = new SysPermission();
        systemMenu.setParentId(0L);
        systemMenu.setPermissionName("系统管理");
        systemMenu.setPermissionType(1);
        systemMenu.setPermissionCode("system");
        systemMenu.setPath("/system");
        systemMenu.setComponent("Layout");
        systemMenu.setIcon("system");
        systemMenu.setSort(1);
        systemMenu.setStatus(1);
        permissionService.save(systemMenu);
        permissions.add(systemMenu);

        // 用户管理菜单
        SysPermission userMenu = new SysPermission();
        userMenu.setParentId(systemMenu.getId());
        userMenu.setPermissionName("用户管理");
        userMenu.setPermissionType(1);
        userMenu.setPermissionCode("system:user");
        userMenu.setPath("/system/user");
        userMenu.setComponent("system/user/index");
        userMenu.setIcon("user");
        userMenu.setSort(1);
        userMenu.setStatus(1);
        permissionService.save(userMenu);
        permissions.add(userMenu);

        // 用户管理按钮
        List<SysPermission> userButtons = new ArrayList<>();
        userButtons.add(createButton(userMenu.getId(), "查询用户", "system:user:list", 1));
        userButtons.add(createButton(userMenu.getId(), "创建用户", "system:user:add", 2));
        userButtons.add(createButton(userMenu.getId(), "更新用户", "system:user:edit", 3));
        userButtons.add(createButton(userMenu.getId(), "删除用户", "system:user:delete", 4));
        userButtons.add(createButton(userMenu.getId(), "重置密码", "system:user:reset-password", 5));
        permissionService.saveBatch(userButtons);
        permissions.addAll(userButtons);

        // 角色管理菜单
        SysPermission roleMenu = new SysPermission();
        roleMenu.setParentId(systemMenu.getId());
        roleMenu.setPermissionName("角色管理");
        roleMenu.setPermissionType(1);
        roleMenu.setPermissionCode("system:role");
        roleMenu.setPath("/system/role");
        roleMenu.setComponent("system/role/index");
        roleMenu.setIcon("role");
        roleMenu.setSort(2);
        roleMenu.setStatus(1);
        permissionService.save(roleMenu);
        permissions.add(roleMenu);

        // 角色管理按钮
        List<SysPermission> roleButtons = new ArrayList<>();
        roleButtons.add(createButton(roleMenu.getId(), "查询角色", "system:role:list", 1));
        roleButtons.add(createButton(roleMenu.getId(), "创建角色", "system:role:add", 2));
        roleButtons.add(createButton(roleMenu.getId(), "更新角色", "system:role:edit", 3));
        roleButtons.add(createButton(roleMenu.getId(), "删除角色", "system:role:delete", 4));
        roleButtons.add(createButton(roleMenu.getId(), "分配权限", "system:role:edit", 5));
        permissionService.saveBatch(roleButtons);
        permissions.addAll(roleButtons);

        // 权限管理菜单
        SysPermission permissionMenu = new SysPermission();
        permissionMenu.setParentId(systemMenu.getId());
        permissionMenu.setPermissionName("权限管理");
        permissionMenu.setPermissionType(1);
        permissionMenu.setPermissionCode("system:permission");
        permissionMenu.setPath("/system/permission");
        permissionMenu.setComponent("system/permission/index");
        permissionMenu.setIcon("permission");
        permissionMenu.setSort(3);
        permissionMenu.setStatus(1);
        permissionService.save(permissionMenu);
        permissions.add(permissionMenu);

        // 权限管理按钮
        List<SysPermission> permissionButtons = new ArrayList<>();
        permissionButtons.add(createButton(permissionMenu.getId(), "查询权限", "system:permission:list", 1));
        permissionButtons.add(createButton(permissionMenu.getId(), "创建权限", "system:permission:add", 2));
        permissionButtons.add(createButton(permissionMenu.getId(), "更新权限", "system:permission:edit", 3));
        permissionButtons.add(createButton(permissionMenu.getId(), "删除权限", "system:permission:delete", 4));
        permissionService.saveBatch(permissionButtons);
        permissions.addAll(permissionButtons);

        // 部门管理菜单
        SysPermission deptMenu = new SysPermission();
        deptMenu.setParentId(systemMenu.getId());
        deptMenu.setPermissionName("部门管理");
        deptMenu.setPermissionType(1);
        deptMenu.setPermissionCode("system:dept");
        deptMenu.setPath("/system/dept");
        deptMenu.setComponent("system/dept/index");
        deptMenu.setIcon("dept");
        deptMenu.setSort(4);
        deptMenu.setStatus(1);
        permissionService.save(deptMenu);
        permissions.add(deptMenu);

        // 部门管理按钮
        List<SysPermission> deptButtons = new ArrayList<>();
        deptButtons.add(createButton(deptMenu.getId(), "查询部门", "system:dept:list", 1));
        deptButtons.add(createButton(deptMenu.getId(), "创建部门", "system:dept:add", 2));
        deptButtons.add(createButton(deptMenu.getId(), "更新部门", "system:dept:edit", 3));
        deptButtons.add(createButton(deptMenu.getId(), "删除部门", "system:dept:delete", 4));
        permissionService.saveBatch(deptButtons);
        permissions.addAll(deptButtons);

        // 登录日志菜单
        SysPermission loginLogMenu = new SysPermission();
        loginLogMenu.setParentId(systemMenu.getId());
        loginLogMenu.setPermissionName("登录日志");
        loginLogMenu.setPermissionType(1);
        loginLogMenu.setPermissionCode("system:login-log");
        loginLogMenu.setPath("/system/login-log");
        loginLogMenu.setComponent("system/login-log/index");
        loginLogMenu.setIcon("log");
        loginLogMenu.setSort(5);
        loginLogMenu.setStatus(1);
        permissionService.save(loginLogMenu);
        permissions.add(loginLogMenu);

        // 登录日志按钮
        List<SysPermission> loginLogButtons = new ArrayList<>();
        loginLogButtons.add(createButton(loginLogMenu.getId(), "查询日志", "system:login-log:list", 1));
        loginLogButtons.add(createButton(loginLogMenu.getId(), "清空日志", "system:login-log:clean", 2));
        permissionService.saveBatch(loginLogButtons);
        permissions.addAll(loginLogButtons);

        return permissions;
    }

    private List<SysUser> initUsers() {
        List<SysUser> users = new ArrayList<>();

        // 超级管理员用户
        SysUser admin = new SysUser();
        admin.setUsername("admin");
        admin.setPassword(md5("123456"));
        admin.setRealName("系统管理员");
        admin.setEmail("admin@example.com");
        admin.setPhone("13800138000");
        admin.setStatus(1);
        users.add(admin);

        // 普通用户
        SysUser user = new SysUser();
        user.setUsername("user");
        user.setPassword(md5("123456"));
        user.setRealName("普通用户");
        user.setEmail("user@example.com");
        user.setPhone("13800138001");
        user.setStatus(1);
        users.add(user);

        // 批量保存用户
        userService.saveBatch(users);
        return users;
    }

    private void initRolePermissions(List<SysRole> roles, List<SysPermission> permissions) {
        // 超级管理员拥有所有权限
        for (SysPermission permission : permissions) {
            rolePermissionService.addRolePermission(roles.get(0).getId(), permission.getId());
        }

        // 普通用户只拥有用户列表相关权限
        for (SysPermission permission : permissions) {
            if (permission.getPermissionCode().startsWith("system:user:list")) {
                rolePermissionService.addRolePermission(roles.get(1).getId(), permission.getId());
            }
        }
    }

    private void initUserRoles(List<SysUser> users, List<SysRole> roles) {
        // 为超级管理员用户分配超级管理员角色
        SysUserRole adminUserRole = new SysUserRole();
        adminUserRole.setUserId(users.get(0).getId());
        adminUserRole.setRoleId(roles.get(0).getId());
        userRoleService.save(adminUserRole);

        // 为普通用户分配普通用户角色
        SysUserRole userRole = new SysUserRole();
        userRole.setUserId(users.get(1).getId());
        userRole.setRoleId(roles.get(1).getId());
        userRoleService.save(userRole);
    }

    private SysPermission createButton(Long parentId, String name, String permission, Integer sort) {
        SysPermission button = new SysPermission();
        button.setParentId(parentId);
        button.setPermissionName(name);
        button.setPermissionType(2);
        button.setPermissionCode(permission);
        button.setSort(sort);
        button.setStatus(1);
        return button;
    }

    /**
     * MD5加密
     */
    private String md5(String password) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] bytes = md.digest(password.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : bytes) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            log.error("MD5加密失败", e);
            return password;
        }
    }
}
